package com.spzx.product.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.constant.Constants;
import com.spzx.common.core.utils.ServletUtils;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.api.domain.Product;
import com.spzx.product.api.domain.ProductDetails;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuStock;
import com.spzx.product.mapper.ProductMapper;
import com.spzx.product.service.ProductDetailsService;
import com.spzx.product.service.ProductService;
import com.spzx.product.service.ProductSkuService;
import com.spzx.product.service.SkuStockService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProductServiceImpl
        extends ServiceImpl<ProductMapper, Product> implements ProductService {
    @Resource
    ProductDetailsService productDetailsService;
    @Resource
    SkuStockService skuStockService;
    @Resource
    ProductSkuService productSkuService;
    @Override
    public Page<Product> selectProductPage(Product product) {
        Integer pageNum = ServletUtils.getParameterToInt(Constants.PAGE_NUM, 1);
        Integer pageSize = ServletUtils.getParameterToInt(Constants.PAGE_SIZE, 3);
        Page<Product> page = new Page<>(pageNum,pageSize);
        //查询分页列表数据
        List<Product> list =  baseMapper.selectProductPage(page , product);
        page.setRecords(list);
        return page;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int saveProduct(Product product) {
        //1、保存product数据: sku和details都需要关联spu的id
        //设置默认参数
        product.setStatus((byte) 0);
        product.setAuditStatus((byte) 0);
        product.setCreateBy(SecurityUtils.getUsername());
        product.setCreateTime(new Date());
        product.setUpdateTime(new Date());
        product.setDelFlag("0");
        this.save(product);
        //获取新增的product的id值
        Long spuId = product.getId();
        //2、保存product_details:  和product是 1:1的关系
        List<String> detailsImageUrlList = product.getDetailsImageUrlList();
        if(!CollectionUtils.isEmpty(detailsImageUrlList)){
            ProductDetails productDetails = new ProductDetails();
            productDetails.setId(spuId); //spu和details是1：1映射，查询到spu后，可以直接使用它的id当作主键查询详情图
            productDetails.setProductId(spuId);
            productDetails.setCreateTime(new Date());
            productDetails.setCreateBy(SecurityUtils.getUsername());
            //将详情图每两个地址使用逗号分割拼接成字符串
            productDetails.setImageUrls(StringUtils.join(detailsImageUrlList,","));
            productDetails.setUpdateTime(new Date());
            productDetails.setDelFlag("0");
            productDetailsService.save(productDetails);
        }
        //3、保存sku数据
        if(!CollectionUtils.isEmpty(product.getProductSkuList())){
            for (int i = 0; i < product.getProductSkuList().size(); i++) {
                ProductSku sku = product.getProductSkuList().get(i);
                //保存sku
                sku.setProductId(spuId);
                //商品码:使用了 hutool-core包中的IdUtil工具类 生成
//            sku.setSkuCode( IdUtil.getSnowflakeNextIdStr());
                sku.setSkuCode(spuId+"_"+ i);
                sku.setCreateBy(SecurityUtils.getUsername());
                //sku标题：使用spu标题+sku的spec值生成
                sku.setSkuName(product.getName()+" "+ sku.getSkuSpec());
                sku.setCreateTime(new Date());
                sku.setUpdateTime(new Date());
                sku.setStatus((byte) 0);
                sku.setDelFlag("0");
                productSkuService.save(sku);
                //保存sku的库存
                SkuStock skuStock = new SkuStock();
                skuStock.setSkuId(sku.getId());
                skuStock.setTotalNum(sku.getStockNum());//库存
                skuStock.setLockNum(0);
                skuStock.setAvailableNum(sku.getStockNum());
                skuStock.setSaleNum(0);
                skuStock.setDelFlag("0");
                skuStock.setUpdateTime(new Date());
                skuStock.setCreateTime(new Date());
                skuStockService.save(skuStock);
            }
            //        product.getProductSkuList().forEach(sku->{
            //            //保存sku
            //            sku.setProductId(spuId);
            //            //商品码:使用了 hutool-core包中的IdUtil工具类 生成
            //           sku.setSkuCode( IdUtil.getSnowflakeNextIdStr());
            //            sku.setCreateBy(SecurityUtils.getUsername());
            //            //sku标题：使用spu标题+sku的spec值生成
            //            sku.setSkuName(product.getName()+" "+ sku.getSkuSpec());
            //            sku.setCreateTime(new Date());
            //            sku.setUpdateTime(new Date());
            //            sku.setStatus((byte) 0);
            //            sku.setDelFlag("0");
            //            productSkuService.save(sku);
            //            //保存sku的库存
            //            SkuStock skuStock = new SkuStock();
            //            skuStock.setSkuId(sku.getId());
            //            skuStock.setTotalNum(sku.getStockNum());//库存
            //            skuStock.setLockNum(0);
            //            skuStock.setAvailableNum(sku.getStockNum());
            //            skuStock.setSaleNum(0);
            //            skuStock.setDelFlag("0");
            //            skuStock.setUpdateTime(new Date());
            //            skuStock.setCreateTime(new Date());
            //            skuStockService.save(skuStock);
            //        });
            //        productSkuService.saveBatch(skus);
                        //4、保存sku_stock数据


        }


        return 1;
    }

    @Override
    public Product selectProductById(Long id) {
        //1、查询spu
        Product product = this.getById(id);
        if(product==null){
            return null;
        }
        //2、查询spu_details
        ProductDetails productDetails = productDetailsService.getById(id);
        if(productDetails!=null){
            product.setDetailsImageUrlList(
                    StringUtils.isEmpty(productDetails.getImageUrls())?null:
                    Arrays.asList(productDetails.getImageUrls().split(",")));

        }
        //3、查询sku
        List<ProductSku> productSkus = productSkuService.list(Wrappers.lambdaQuery(ProductSku.class)
                .eq(ProductSku::getProductId, id));
        if(!CollectionUtils.isEmpty(productSkus)){
            productSkus.forEach(productSku -> {
                //4、查询sku的库存
                SkuStock skuStock = skuStockService.getOne(Wrappers.lambdaQuery(SkuStock.class)
                        .eq(SkuStock::getSkuId, productSku.getId())
                        .last("limit 1"));
                productSku.setStockNum(skuStock.getTotalNum());
            });
        }
        product.setProductSkuList(productSkus);
        return product;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateStatus(Long id, Integer status) {
        //更新product表的上下架状态
        this.update(Wrappers.lambdaUpdate(Product.class)
                .eq(Product::getId , id)
                .set(Product::getStatus ,status )
                .set(Product::getUpdateBy , SecurityUtils.getUsername()));
        //更新spu下sku的上下架状态： sku表
        productSkuService.update(Wrappers.lambdaUpdate(ProductSku.class)
                .eq(ProductSku::getProductId , id)
                .set(ProductSku::getStatus,status)
                .set(ProductSku::getUpdateBy , SecurityUtils.getUsername()));

        return 1;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateProduct(Product product) {
        //1、更新product数据: sku和details都需要关联spu的id
        //设置默认参数
        if(product.getId()==null){
            return 0;
        }
        product.setUpdateBy(SecurityUtils.getUsername());
        this.updateById(product);

        Long spuId = product.getId();
        //2、更新product_details:  和product是 1:1的关系
        List<String> detailsImageUrlList = product.getDetailsImageUrlList();
        if(!CollectionUtils.isEmpty(detailsImageUrlList)){
            ProductDetails productDetails = new ProductDetails();
            productDetails.setId(spuId); //spu和details是1：1映射，查询到spu后，可以直接使用它的id当作主键查询详情图
            productDetails.setUpdateBy(SecurityUtils.getUsername());
            //将详情图每两个地址使用逗号分割拼接成字符串
            productDetails.setImageUrls(StringUtils.join(detailsImageUrlList,","));
            productDetailsService.updateById(productDetails);
        }
        //3、更新sku数据
        if(!CollectionUtils.isEmpty(product.getProductSkuList())){
            for (int i = 0; i < product.getProductSkuList().size(); i++) {
                ProductSku sku = product.getProductSkuList().get(i);
                sku.setUpdateBy(SecurityUtils.getUsername());
                //sku标题：使用spu标题+sku的spec值生成
                sku.setSkuName(product.getName()+" "+ sku.getSkuSpec());
                productSkuService.updateById(sku);
                //更新sku的库存
                //使用sku的id作为条件查询库存数据进行更新： 一个sku如果只有一个仓库库存信息 可以按照此方式更新
                skuStockService.update(Wrappers.lambdaUpdate(SkuStock.class)
                        .eq(SkuStock::getSkuId , sku.getId())
                        .set(SkuStock::getTotalNum , sku.getStockNum() )
                        .set(SkuStock::getAvailableNum , sku.getStockNum())
                        .set(SkuStock::getUpdateBy , SecurityUtils.getUsername()));
            }
        }


        return 1;
    }

    @Override
    public int removeProductById(Long id) {
        //1、删除product：根据id删除
        this.removeById(id);
        //2、删除product_details:根据id删除
        productDetailsService.removeById(id);
        //3、删除sku列表：
        //先查询sku集合，为了得到sku的id集合  删除库存时使用
        List<Long> skuIds = productSkuService.list(Wrappers.lambdaQuery(ProductSku.class)
                        .eq(ProductSku::getProductId, id)
                )
                //获取list集合的stream流
                .stream()
                //遍历流中的每个元素，只获取该对象的id属性值返回 ， 最后将前面返回的所有id存到一个list集合中
                .map(ProductSku::getId).collect(Collectors.toList());
        productSkuService.removeBatchByIds(skuIds);//批量删除sku
        //4、删除库存： 根据skuStock的  skuid的集合删除
        skuStockService.remove(Wrappers.lambdaQuery(SkuStock.class)
                .in(SkuStock::getSkuId , skuIds));
        return 1;
    }

//    public static void main(String[] args) {
//        System.out.println("IdUtil.getSnowflakeNextIdStr() = " + IdUtil.getSnowflakeNextIdStr());
//    }
}